#pragma once

#include "stdafx.h"
#include "NtPoint.h"
#include "NtRect.h"

#define DeclarePropertyIO(CLSNAME, TYPE, TID)									\
CLSNAME(const std::string& rkName) { m_kName = rkName; }						\
operator TYPE() const { return m_Value; }										\
void SetPropertyValue(TYPE Value) { m_Value= Value; m_kPropType= TID; }			\
TYPE GetPropertyValue() const { return m_Value; }								\
TYPE operator()() const { return m_Value; }										\
void operator= ( TYPE value) { m_Value= value; }								\
protected: TYPE m_Value;

#define DeclarePropertyIO_R(CLSNAME, TYPE, TID)									\
CLSNAME(const std::string& rkName) { m_kName = rkName;  }						\
operator TYPE() const { return m_Value; }										\
void SetPropertyValue(const TYPE& Value) { m_Value= Value; m_kPropType= TID; }	\
const TYPE& GetPropertyValue() const { return m_Value; }						\
const TYPE operator()() const { return m_Value; }								\
void operator= ( const TYPE& value) { m_Value= value; }							\
protected: TYPE m_Value;

enum NtPropertyDataType
{
	PDT_UNKNOW = 0,
	PDT_BOOL,
	PDT_INT,
	PDT_UINT,
	PDT_FLOAT,
	PDT_DOUBLE,
	PDT_PTR,
	PDT_POINT,
	PDT_RECT,
	PDT_STRING,
	PDT_DWORD,
	PDT_END,
};

class NtAbsProperty
{
public:
	NtAbsProperty()
	: m_kPropType(PDT_UNKNOW) {}

	virtual ~NtAbsProperty() {}

	const std::string& GetPropertyName() const 
	{
		return m_kName;
	}

	const NtPropertyDataType GetDataType() const
	{
		return m_kPropType;
	}

protected:
	std::string m_kName;
	NtPropertyDataType m_kPropType;
};

class NtBoolProperty: public NtAbsProperty
{
public:
	DeclarePropertyIO(NtBoolProperty, BOOL, PDT_BOOL);
};

class NtFloatProperty: public NtAbsProperty
{
public:
	DeclarePropertyIO(NtFloatProperty, float, PDT_FLOAT);
};

class NtIntProperty: public NtAbsProperty
{
public:
	DeclarePropertyIO(NtIntProperty, int, PDT_INT);
};

class NtUIntProperty: public NtAbsProperty
{
public:
	DeclarePropertyIO(NtUIntProperty, unsigned int, PDT_UINT);
};

class NtDoubleProperty: public NtAbsProperty
{
public:
	DeclarePropertyIO(NtDoubleProperty, double, PDT_DOUBLE);
};

class NtStringProperty: public NtAbsProperty
{
public:
	DeclarePropertyIO_R(NtStringProperty, std::string, PDT_STRING);
};

class NtPointProperty: public NtAbsProperty
{
public:
	DeclarePropertyIO_R(NtPointProperty, NtPoint, PDT_POINT);
};

class NtRectProperty: public NtAbsProperty
{
public:
	DeclarePropertyIO(NtRectProperty, NtRect, PDT_RECT);
};

class NtPtrProperty: public NtAbsProperty
{
public:
	DeclarePropertyIO(NtPtrProperty, void*, PDT_PTR);
};

class NtDwordProperty: public NtAbsProperty
{
public:
	DeclarePropertyIO(NtDwordProperty, DWORD, PDT_DWORD);
};

